package com.yenlien.traceyun.control.service;

import com.yenlien.traceyun.control.dao.CompanyModelCategoryDao;
import com.yenlien.traceyun.control.dao.ModelCategoryDao;
import com.yenlien.traceyun.control.dao.ModelCropDao;
import com.yenlien.traceyun.control.entity.ModelCategory;
import com.yenlien.traceyun.control.interceptor.UserAuthUtil;
import com.yenlien.traceyun.control.service.rest.FileRestService;
import com.yenlien.traceyun.control.view.ModelCategoryTree;
import com.yenlien.traceyun.webase.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;

/**
 * @author: bigwangy@sina.com
 * @create: 2020-11-18
 * @description:
 **/

@Service
public class ModelCategoryService {

    @Autowired
    private ModelCategoryDao modelCategoryDao;

    @Autowired
    private FileRestService fileRestService;

    @Autowired
    private ModelCropDao modelCropDao;

    @Autowired
    private ModelCropService modelCropService;

    @Autowired
    private CompanyModelCategoryDao companyModelCategoryDao;


    /**
     * 根据id加载
     *
     * @param id
     * @return
     */
    public ModelCategory load(String id) {
        return modelCategoryDao.findById(id).get();
    }

    /**
     * 查子节点
     *
     * @param id
     * @return
     */
    public List<ModelCategory> loadChild(String id) {
        return modelCategoryDao.findByParentId(id);
    }

    /**
     * 加载所有按sortnum排序
     *
     * @return
     */
    public List<ModelCategory> findAllSort(String companyId) {
        if (StringUtils.isEmpty(companyId)) {
            return modelCategoryDao.findAll(Sort.by(Sort.Direction.ASC, "sortNum"));
        } else {
            List<ModelCategory> all = modelCategoryDao.findAll(Sort.by(Sort.Direction.ASC, "sortNum"));
            List<ModelCategory> root = modelCategoryDao.findByCompanyId(companyId);
            List<ModelCategory> result = new ArrayList<>();
            parse(root, result, all);
            ;
            return result;
        }
    }


    /**
     * 加载根节点
     *
     * @return
     */
    public List<ModelCategory> getRoot() {
        return modelCategoryDao.findRoot();
    }

    public List<ModelCategory> get2Level(String id) {
        return modelCategoryDao.get2Level(id);
    }

    /**
     * 保存
     *
     * @param category
     * @param files
     * @return
     * @throws Exception
     */
    public ModelCategory save(ModelCategory category, List<MultipartFile> files) throws Exception {
        ModelCategory p = modelCategoryDao.findByName(category.getName());
        if (StringUtils.isEmpty(category.getId())) {
            if (p != null) {
                throw new BusinessException("500", "名称【" + category.getName() + "】已存在");
            }
            fileRestService.upload(null, category, files);
        } else {
            int bindsize = companyModelCategoryDao.countByCategoryId(category.getId());
            if (bindsize > 0) {
                throw new BusinessException("500", "已绑定企业不能删除");
            }
            if (p != null && !p.getId().equals(category.getId())) {
                throw new BusinessException("500", "名称【" + category.getName() + "】已存在");
            }
            fileRestService.upload(category, category, files);
        }
        ModelCategory modelCategory = null;
        try {
            modelCategory = modelCategoryDao.save(category);
        } catch (DataIntegrityViolationException e) {
            throw new BusinessException("分类编码不能重复");
        }
        return modelCategory;
    }

    /**
     * 删除
     *
     * @param id
     * @param deleType(0全部删除，1部分删除)
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public void dele(String id, int deleType) {
        ModelCategory modelCategory = modelCategoryDao.findById(id).get();
        int bindsize = companyModelCategoryDao.countByCategoryId(id);
        if (bindsize > 0) {
            throw new BusinessException("500", "已绑定企业不能删除");
        }
        //根节点则全部删除
        if (deleType == 0) {
            dele(modelCategory);
        } else {//部分删除
            List<ModelCategory> child = modelCategoryDao.findByParentId(modelCategory.getId());
            if (child != null && child.size() > 0) {
                for (ModelCategory item : child) {
                    item.setParentId(modelCategory.getParentId());
                }
                //保存并结束
                modelCategoryDao.deleteById(id);
                modelCategoryDao.saveAll(child);
                modelCropService.delteByCategoryId(id);
            } else {//如果没有子节点
                dele(modelCategory);
            }
        }
    }

    public void dele(ModelCategory modelCategory) {
        List<ModelCategory> start = new ArrayList<>();
        start.add(modelCategory);
        List<ModelCategory> modelCategoryList = findAllSort(null);
        List<String> choosed = new ArrayList<>();
        parseIds(start, choosed, modelCategoryList);
        //删除所有分类
        modelCategoryDao.deleteByIdIn(choosed);
        //删除所有作物
        List<String> modelCropIds = modelCropDao.findIdsByCategoryIdIn(choosed);
        modelCropService.deleIds(modelCropIds);
    }


    /**
     * 获取树桩结构
     *
     * @return
     */
    public List<ModelCategoryTree> getTree(String companyId) {
        List<ModelCategory> categoriesAll = findAllSort(companyId);
        List<ModelCategoryTree> root = ModelCategoryTree.create(findRoot(categoriesAll));
        parse(root, categoriesAll);
        return root;
    }


    public List<ModelCategoryTree> loadRootByCompanyId(String companyId) {
        String parentId = modelCropDao.getParentId(UserAuthUtil.getLoginUser().getCompanyId());
        List<ModelCategory> root;
        if ("1".equals(parentId)) {
            // 上级是超管，则直接查询该企业绑定的一级分类
            root = modelCategoryDao.getModelCategory(companyId);
        } else {
            // 上层是政企则查询政企的一级分类
            root = modelCategoryDao.getByCompanyId(parentId);
        }
        if (root == null || root.size() == 0) {
            return new ArrayList<>();
        }
        List<ModelCategory> all = modelCategoryDao.findAll(Sort.by(Sort.Direction.ASC, "sortNum"));
        List<ModelCategory> temp = new ArrayList<>();
        parse(root, temp, all);
        List<ModelCategoryTree> result = ModelCategoryTree.create(findRoot(temp));
        parse(result, temp);
        return result;
    }


    /**
     * 获取父亲ids
     *
     * @param currentId
     */
    public void getParentIds(String currentId, List<String> ids) {
        if (!StringUtils.isEmpty(currentId)) {
            ids.add(currentId);
            Optional<ModelCategory> current = modelCategoryDao.findById(currentId);
            if (current.isPresent()) {
                getParentIds(current.get().getParentId(), ids);
            }
        }

    }

    /**
     * 递归生成tree
     *
     * @param trees
     */
    public void parse(List<ModelCategoryTree> trees, List<ModelCategory> modelCategoryAll) {
        if (trees != null && trees.size() > 0) {
            for (ModelCategoryTree tree : trees) {
                List<ModelCategory> child = findChild(tree.getId(), modelCategoryAll);
                if (child != null && child.size() > 0) {
                    tree.getChildren().addAll(ModelCategoryTree.create(child));
                    parse(tree.getChildren(), modelCategoryAll);
                }
            }
        }
    }

    /**
     * 根据起始位置招树
     *
     * @param start
     * @param chooseNodes
     * @param modelCategoryAll
     */
    public void parse(List<ModelCategory> start, List<ModelCategory> chooseNodes, List<ModelCategory> modelCategoryAll) {
        if (start != null && start.size() > 0) {
            for (ModelCategory modelCategory : start) {
                chooseNodes.add(modelCategory);
                List<ModelCategory> child = findChild(modelCategory.getId(), modelCategoryAll);
                if (child != null && child.size() > 0) {
                    parse(child, chooseNodes, modelCategoryAll);
                }
            }
        }
    }

    /**
     * 根据起始位置招树
     *
     * @param start
     * @param chooseNodes
     * @param modelCategoryAll
     */
    public void parseIds(List<ModelCategory> start, List<String> chooseNodes, List<ModelCategory> modelCategoryAll) {
        if (start != null && start.size() > 0) {
            for (ModelCategory modelCategory : start) {
                chooseNodes.add(modelCategory.getId());
                List<ModelCategory> child = findChild(modelCategory.getId(), modelCategoryAll);
                if (child != null && child.size() > 0) {
                    parseIds(child, chooseNodes, modelCategoryAll);
                }
            }
        }
    }


    /**
     * 查找子节点
     *
     * @param parentId
     * @param categories
     * @return
     */
    private List<ModelCategory> findChild(String parentId, List<ModelCategory> categories) {
        List<ModelCategory> modelCategories = new ArrayList<>();
        if (categories != null && categories.size() > 0) {
            Iterator<ModelCategory> iterator = categories.iterator();
            while (iterator.hasNext()) {
                ModelCategory modelCategory = iterator.next();
                if (parentId.equals(modelCategory.getParentId())) {
                    modelCategories.add(modelCategory);
                    iterator.remove();
                }
            }
        }
        return modelCategories;
    }

    /**
     * 查询父节点
     *
     * @param categories
     * @return
     */
    private List<ModelCategory> findRoot(List<ModelCategory> categories) {
        List<ModelCategory> modelCategories = new ArrayList<>();
        if (categories != null && categories.size() > 0) {
            Iterator<ModelCategory> iterator = categories.iterator();
            while (iterator.hasNext()) {
                ModelCategory modelCategory = iterator.next();
                if (StringUtils.isEmpty(modelCategory.getParentId())) {
                    modelCategories.add(modelCategory);
                    iterator.remove();
                }
            }
        }
        return modelCategories;
    }

}
